package sg.edu.nus.iss.billing.util;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.util.Random;

import sg.edu.nus.iss.billing.controller.AccountController;
import sg.edu.nus.iss.billing.controller.CustomerComplaintController;
import sg.edu.nus.iss.billing.entity.Account;
import sg.edu.nus.iss.billing.entity.CustomerComplaint;
import sg.edu.nus.iss.billing.exception.ControllerException;


/**
 * @author sammil
 *
 */

public class UniqueKeyGenerator {
	
	private static final char[] alphabetSymbols = new char[26];
	private static final Random random = new Random();
	private static final String acctNoPrefix = "1.1";
	private static final int mobileVoiceNoPrefix = 9;
	private static final int digitalVoiceNoPrefix = 6;
	private static final String complaintNoPrefix = "C";
	private static final String generatedPhNoFile = "data/generated-phone-nos.txt";
	
	static {
		for (int idx = 0; idx < 26; idx++){
			alphabetSymbols[idx] = (char) ('A' + idx);
		}
	}
	
	public static String createUniqueAccountNo() {
		
		String accountNumber = "";
		accountNumber = acctNoPrefix + generateRandomNo(7) + getAlphaRandomString(1);
		AccountController  acctControllerObj = new AccountController();
		Account acct = null;
		try {
			acct = acctControllerObj.isAccountExist(accountNumber);
		} catch (ControllerException e) {
			e.printStackTrace();
		}
		//IF Acct No already exists, generate New One
		if(acct != null){
			accountNumber = createUniqueAccountNo();
		}
		return accountNumber;
	}
	
	public static String createUniqueMobileVoiceNo() {
		
		String mobileNo = "";
		mobileNo = mobileVoiceNoPrefix + generateRandomNo(7);
		if(isPhoneNoAllreadyExists(mobileNo)){
			//If Ph No already exists, generate New One
			mobileNo = createUniqueMobileVoiceNo();
		} else {
			storePhoneNo(mobileNo);
		}
		return mobileNo;
	}
	

	public static String createUniqueDigitalVoiceNo() {
		
		String digitalVoiceNo = "";
		digitalVoiceNo = digitalVoiceNoPrefix + generateRandomNo(7);

		if(isPhoneNoAllreadyExists(digitalVoiceNo)){
			//If Ph No already exists, generate New One
			digitalVoiceNo = createUniqueDigitalVoiceNo();
		} else {
			storePhoneNo(digitalVoiceNo);
		}
		return digitalVoiceNo;
	}
    
	public static String createUniqueComplaintNo(){
		
		String complaintRefKey = null;
		complaintRefKey = complaintNoPrefix + generateRandomNo(6);
		CustomerComplaint customerComplaint = null;
		CustomerComplaintController customerComplaintController = new CustomerComplaintController();
		try {
			customerComplaint = customerComplaintController.findCustomerComplaintByReference(complaintRefKey);
		} catch (ControllerException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		if(customerComplaint != null){
			complaintRefKey = createUniqueComplaintNo();
		}
		return complaintRefKey ;
	}
	public static String getAlphaRandomString(int length) {
		
		char[] buf =  new char[length];
		for (int idx = 0; idx < buf.length; ++idx)
		buf[idx] = alphabetSymbols[random.nextInt(alphabetSymbols.length)];
		return new String(buf);
	}
		
	public static String generateRandomNo(int digits){
		StringBuffer randomNoStr = new StringBuffer();
		for(int i=0;i<digits;i++) randomNoStr.append(random.nextInt(9));
		return randomNoStr.toString();
	}
	
	private static synchronized boolean isPhoneNoAllreadyExists(String phoneNo){
		
		File phNoFile = new File(generatedPhNoFile);
		if(!phNoFile.exists()) return false;
		boolean isExists = false;
		  try{
				FileReader fstream = null;
				BufferedReader br = null;
				fstream = new FileReader(phNoFile);
				br = new BufferedReader(fstream);
				String s = null;
				while((s = br.readLine()) != null) {
					if(s.trim().equals(phoneNo)){
						isExists = true;
						break;
					}
				} 
				br.close();
				fstream.close();
		    }catch (Exception e){
		      System.err.println("isPhoneNoAllreadyExists Error : " + e.getMessage());
		    }
		return isExists;
	}
	
	private static synchronized void storePhoneNo(String phoneNo){
		
	File phNoFile = new File(generatedPhNoFile);
	  try{
		    FileWriter fstream = new FileWriter(phNoFile,true);
		    BufferedWriter out = new BufferedWriter(fstream);
		    out.write(phoneNo);
		    out.newLine();
		    out.close();
		    }catch (Exception e){
		      System.err.println("storePhoneNo Error: " + e.getMessage());
		    }
	}

	public static void main (String s[]){
		System.out.println("Account No :"+ createUniqueAccountNo());
		System.out.println("DV No :"+ createUniqueDigitalVoiceNo());
		System.out.println("Mobile No :"+ createUniqueMobileVoiceNo());
		System.out.println("createUniqueComplaintNo :"+ createUniqueComplaintNo());
	}

	
}
